#ifndef _X_DISPATCH_H
#define _X_DISPATCH_H
#include "xDef.h"
#include <iostream>
#include <map>
#include <functional>
namespace xNet
{
    template <class T>
    NET_ENGINE_CORE_API class MessageCallback{
        public:
            virtual bool exec(T* t,uint16 cmd,void* arg)=0;
    };

    template <class T>
    NET_ENGINE_CORE_API class CallbackFun : public MessageCallback<T>{
        public:
            typedef std::function<bool(T*,uint16,void*)> CFunction;
            CallbackFun():func(nullptr){}
            CallbackFun(const CFunction& _func):func(_func){}
            bool exec(T* t,uint16 cmd_type,void* arg){
                if(func == nullptr) return false;
                return func(t,cmd_type,arg);
            }
        private:
            CFunction func;
    };
    template <class T>
    NET_ENGINE_CORE_API class DispatchHandle{
        public:
            DispatchHandle() { m_mapRegFun.clear(); }
            ~DispatchHandle() {
                m_mapRegFun.clear();
            }
        public:
            bool Dispatch(T* t,uint16 cmd_type,void* arg){
                if(m_mapRegFun.find(cmd_type) == m_mapRegFun.end()) return false;
                CallbackFun<T> func = m_mapRegFun[cmd_type];
                return func.exec(t,cmd_type,arg);
            }
            void RegFunc(uint16 cmd_type,const CallbackFun<T>& cbfun){
                if(m_mapRegFun.find(cmd_type) != m_mapRegFun.end()) return ;
                //m_mapRegFun[cmd_type] = cbfun;
                m_mapRegFun.insert(std::pair<uint16,CallbackFun<T> >(cmd_type,cbfun));
            }
            bool VaildCmd(uint16 cmd_type){
                return m_mapRegFun.find(cmd_type) != m_mapRegFun.end();
            }
        private:
            std::map<uint16,CallbackFun<T> > m_mapRegFun;
    };
}

#endif